package com.yeyaomai.dksns.flowis.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Order;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
//import com.mongodb.BasicDBObjectBuilder;
//import com.mongodb.DBObject;
import com.yeyaomai.dksns.flowis.dao.DetailDao;
import com.yeyaomai.dksns.flowis.domain.LatestRefer;
import com.yeyaomai.dksns.flowis.domain.PvIpValue;
import com.yeyaomai.dksns.flowis.domain.Today;
import com.yeyaomai.dksns.flowis.domain.flowisdetail.FlowisQueryOrder;
import com.yeyaomai.dksns.flowis.domain.flowisdetail.FlowisStatDetailDTO;
import com.yeyaomai.dksns.flowis.service.FlowisQueryService;
import com.yeyaomai.dksns.flowis.util.CollectionNames;
import com.yeyaomai.dksns.flowis.util.NumberFormatUtils;
import com.yeyaomai.dksns.flowis.util.VelocityToolDateUtils;

/**
 * 
 * @author dingtao@yeyaomai.com
 * 
 */

@Service
public class FlowisQueryServiceImpl implements FlowisQueryService {

	//private static Logger logger = LoggerFactory.getLogger(FlowisQueryServiceImpl.class);

	@Autowired
	private DetailDao detailDao;

	@Override
	public Page<FlowisStatDetailDTO> getSplit(FlowisQueryOrder order) {

		Date enddate = new Date(); // 现在时间

		Date startdate = null;

		// 今天是 0 昨天 -1 前天 是 -2 以此类推

		int day = NumberFormatUtils.resolveString(order.getDay(), 0);

		startdate = DateUtils.truncate(DateUtils.addDays(enddate, day),
				Calendar.DATE);// 截段日期
		if (!order.isPeriod()) // 最近7天 最近 30天
		{
			enddate = DateUtils.addDays(startdate, 1);
		}

		// 如果是 -1 代表 全天查询
		int hour = NumberFormatUtils.resolveString(order.getHour(), -1);

		if (StringUtils.isNotEmpty(order.getHour()) && hour > -1
				&& !order.isPeriod()) {

			startdate = DateUtils.addHours(startdate,
					Integer.valueOf(order.getHour()));

			enddate = DateUtils.addHours(startdate, +1);
		}

		order.setNumber(NumberFormatUtils.resolveString(order.getNumber(), 1)
				+ "");


		order.setStartTime(VelocityToolDateUtils.formathour.format(startdate));

		order.setEndTime(VelocityToolDateUtils.formathour.format(enddate));

		return detailDao.getSplit(order);
	}

	public Page<FlowisStatDetailDTO> getOnlineStatus(FlowisQueryOrder order) {
		Date date = new Date(); // 现在时间

		String startdate = "";
		String enddate = VelocityToolDateUtils.format.format(date);
		startdate = VelocityToolDateUtils.format
				.format(date.getTime() - 900 * 1000);

		order.setNumber(NumberFormatUtils.resolveString(order.getNumber(), 1)
				+ "");

		order.setStartTime(startdate);

		order.setEndTime(enddate);

		return detailDao.getSplit(order);
	}

	@Override
	public List<FlowisStatDetailDTO> getDescbyCondition(LinkedHashMap<String,String> queryArgs) {

		return detailDao.getLastNumberByCondition(queryArgs);

	}

	public void insert(FlowisStatDetailDTO dto) {
		detailDao.insert(dto);
	}

	/**
	 * 处理PV
	 */
	private int getPageViewByTime(String fromdate, String todate) {

		Query query = new Query(Criteria.where("access_date").gte(fromdate)
				.lt(todate));
		int pvcount = (int) detailDao.getTotalSize(query,
				FlowisStatDetailDTO.class);
		return pvcount;
	}

	/**
	 * 处理IP
	 */
	private int getIpByTime(String fromdate, String todate) {
		String mapFunction = "{ip: 0}";
		String reduceFunction = "function(doc, prev) {prev.ip+=1}";
		Criteria criteria = Criteria.where("access_date").gte(fromdate)
				.lte(todate);
		int ipcount = detailDao.group(criteria, CollectionNames.IP,
				mapFunction, reduceFunction, FlowisStatDetailDTO.class)
				.getKeys();
		return ipcount;
	}

	public List<FlowisStatDetailDTO> getDateByOnline(Date date) {
		List<FlowisStatDetailDTO> flowList = new ArrayList<FlowisStatDetailDTO>();
		List<FlowisStatDetailDTO> list = new ArrayList<FlowisStatDetailDTO>();
		String fromdate = "";
		String todate = "";
				try {
					fromdate = VelocityToolDateUtils.format
							.format(VelocityToolDateUtils.format
									.parse(VelocityToolDateUtils.format.format(date
											.getTime() - 15 * 60 * 1000)));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				todate = VelocityToolDateUtils.format.format(date);
			flowList = detailDao.findList(Criteria.where("access_date").gte(fromdate).lt(todate));
		   // flowList = this.handle(flowList);
		    Map<String,PvIpValue> map = new HashMap<String,PvIpValue>();
		    map = this.handleMap(flowList);
		    for (Iterator<String> iterator = map.keySet().iterator(); iterator.hasNext();) {
				String value = (String) iterator.next();
				FlowisStatDetailDTO flow = new FlowisStatDetailDTO();
				PvIpValue pvip = map.get(value);
				flow.setAccess_date(value);
				flow.setPv(pvip.getPv());
				flow.setIpCount(pvip.getIp().size());
				list.add(flow);
			}
		return list;
	}
	
	private Map<String,PvIpValue> handleMap(List<FlowisStatDetailDTO> flowList){
		
		Map<String, PvIpValue> flowMap=new HashMap<String, PvIpValue>();
		for(FlowisStatDetailDTO flow:flowList){
			PvIpValue iv = new PvIpValue();
			String key = flow.getFromatDate();
			if(flowMap.containsKey(key)){
				iv=flowMap.get(key);
				iv.getIp().add(flow.getIp());
				iv.setPv(iv.getPv()+1);
				iv.setIp(iv.getIp());
				flowMap.put(key, iv);
			}else{
				Set<String> ip=new HashSet<String>();
				ip.add(flow.getIp());
				iv.setIp(ip);
				iv.setPv(1);
				flowMap.put(key, iv);
			}
			
		}
		return flowMap;
	}
	
	public Map<String, Integer> getDateByOnlineCount(Date date) {
		String fromdate = "";
		String todate = "";
		Map<String, Integer> map = new HashMap<String, Integer>();
		try {
			fromdate = VelocityToolDateUtils.format
					.format(VelocityToolDateUtils.format
							.parse(VelocityToolDateUtils.format.format(date
									.getTime() - 15 * 60 * 1000)));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		todate = VelocityToolDateUtils.format.format(date);

		int pv = this.getPageViewByTime(fromdate, todate);
		int ipCount = this.getIpByTime(fromdate, todate);
		map.put("pv", pv);
		map.put("ip", ipCount);
		return map;
	}

	@SuppressWarnings("unchecked")
	public List<LatestRefer> getLatestRefer() {
		{
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			Calendar c = Calendar.getInstance();
			Date etd = c.getTime();
			String et = format.format(etd);
			
			c.add(Calendar.MINUTE, -15);
			Date std = c.getTime();
			String st = format.format(std);
			
//			st="2012-01-01";
//			et="2013-01-01";
			String mapFunction = "{ count: 0}";
			String reduceFunction = "function(key,values) {values.referer,values.count+=1}";
			Criteria criteria = Criteria.where("referer").ne("null")
					.and("access_date").gte(st).lt(et);
			String[] groups = { CollectionNames.REFERER };
			GroupByResults<LatestRefer> referGroupResults = detailDao.groups(
					criteria, mapFunction, reduceFunction, LatestRefer.class,
					groups);

			ArrayList<LatestRefer> latestreferList = new ArrayList<LatestRefer>();

			for (LatestRefer latestRefer : referGroupResults) {
				latestreferList.add(latestRefer);
			}
			Collections.sort(latestreferList);
			return latestreferList;

		}
	}
	
	@Override
	public void update(String stoptime, String  close, String cookieId) {
		
		String st = VelocityToolDateUtils.getDay(0);
		String et = VelocityToolDateUtils.getDay(1);
		FlowisStatDetailDTO flowis = new FlowisStatDetailDTO();
		
		Query query = new Query(Criteria.where("cookieId").is(cookieId)
				.and("access_date").gte(st).lt(et));
		query.sort().on("access_date", Order.DESCENDING);
		List<FlowisStatDetailDTO> flowisList = detailDao.findList(query);
		
		if(flowisList.size() >0){
			
			flowis = flowisList.get(0);
			Integer time = Integer.valueOf(stoptime)<=18000 ? Integer.valueOf(stoptime) : 18000;
			Update update = Update.update("stoptime", time);
			if(close != null && close != ""){
				update.set("close", close);
			}
			detailDao.update(Criteria.where("_id").is(flowis.getId()), update);
			
		}
		
	}

	/**
	 * 今日统计实时
	 */
	@Override
	public Today findFlowisStatDetailDTOByTime(Date date) {
		
		return detailDao.findFlowisStatDetailDTOByTime(date);
	}
}
